package net.bithappens.hnqe.scratchpad;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;




public class CreateTestDataScriptForSOSE{
	
	private Random random = new Random();
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
	
	private Map<ServiceType, Integer> serviceCount = new HashMap<ServiceType, Integer>();
	private Map<ServicePropertyType, Integer> servicePropertyCount = new HashMap<ServicePropertyType, Integer>();
	
	private BufferedWriter out;
	
	
	public CreateTestDataScriptForSOSE(BufferedWriter out) {
		this.out = out;
	}


	public static void main(String[] args) throws IOException {
		
		
		FileWriter fstream = new FileWriter("testData.txt");
		BufferedWriter out = new BufferedWriter(fstream);

		CreateTestDataScriptForSOSE ctds = new CreateTestDataScriptForSOSE(out);
		
		ctds.createServiceNodes(500);
		
		ctds.createServicePropertyNodes(300);
		
		ctds.createPropertyRelation(600);
		
		ctds.createSimilarityRelationship(700);
		
		ctds.createForwardingRelationship(200);
		
		out.flush();
		
		out.close();
	}
	
	
	
	private enum ServiceType {
		SBS, HPS
	}

	private int getServiceCounter(ServiceType type) {
		if(serviceCount.containsKey(type)){
			return serviceCount.get(type);
		}
		serviceCount.put(type, 0);
		return 0;
	}

	private ServiceType getServiceType() {
		switch(random.nextInt(2)){
		case 0: return ServiceType.SBS;
		default: return ServiceType.HPS;
		}
	}
	
	public void createServiceNodes(int count) throws IOException{
			
		int x = 0;
		while(x < count){
			ServiceType serviceType = getServiceType();
			Integer counter = getServiceCounter(serviceType);
			out.write(
				"<node uri=\"http://sose.com/node/"+serviceType.name()+"_"+ counter+"\" nodeType=\""+serviceType.name()+"\">\n" +
					"\t<property name=\"name\" type=\"String\">name_" + serviceType + "_" + counter + "</property>\n" +
					"\t<property name=\"description\" type=\"String\">description for " + serviceType + "_" + counter + "</property>\n" +
					"\t<property name=\"configSkill\" type=\"String\">config skill" + serviceType + "_" + counter + "</property>\n" +
				"</node>\n\n"
			);
			x++;
			counter++;
			serviceCount.put(serviceType, counter);
		}
	}


	
	
	private enum ServicePropertyType {
		DataContract, ServiceContract, 
		NonFunctionalProperty, FunctionalProperty
	}
	
	private int getServicePropertyCounter(ServicePropertyType servicePropertyType) {
		if(servicePropertyCount.containsKey(servicePropertyType)){
			return servicePropertyCount.get(servicePropertyType);
		}
		servicePropertyCount.put(servicePropertyType, 0);
		return 0;
	}
	
	private ServicePropertyType getServicePropertyType() {
		switch(random.nextInt(4)){
		case 0: return ServicePropertyType.DataContract;
		case 1: return ServicePropertyType.ServiceContract;
		case 2: return ServicePropertyType.NonFunctionalProperty;
		default: return ServicePropertyType.FunctionalProperty;	
		}
	}
	
	private void createServicePropertyNodes(int count) throws IOException {
		
		int x = 0;
		while(x < count){
			
			ServicePropertyType serviceProperty = getServicePropertyType();
			Integer counter = getServicePropertyCounter(serviceProperty);
			out.write(
				"<node uri=\"http://sose.com/node/"+serviceProperty.name()+"_" + counter +"\" nodeType=\"serviceProperty\">\n" +
					"\t<property name=\"type\" type=\"String\">" + serviceProperty.name() + "</property>\n" +
					"\t<property name=\"name\" type=\"String\">name_" + serviceProperty + "_" + counter + "</property>\n" +
					"\t<property name=\"description\" type=\"String\">description for " + serviceProperty + "_" + counter + "</property>\n" +
				"</node>\n\n"
			);
			x++;
			counter++;
			servicePropertyCount.put(serviceProperty, counter);
		}

	}
	
	
	
	public void createPropertyRelation(int count) throws IOException{
		
		int x = 0;
		while(x < count){
			
			ServiceType serviceType = getServiceType();
			int countService = getServiceCounter(serviceType);
			countService = random.nextInt(countService);
			
			ServicePropertyType serviceProperty = getServicePropertyType();
			int countProperty = getServicePropertyCounter(serviceProperty);
			countProperty = random.nextInt(countProperty);
			
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/PropertyRelationship/id_"+x+"/\" relationType=\"servicePropertyRelation\">\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/"+serviceType.name()+"_"+ countService+"\"/>\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/"+serviceProperty.name()+"_"+countProperty+"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			x++;
		}
	}

	
	
	public void createSimilarityRelationship(int count) throws IOException {

		int x = 0;
		while(x < count){
		
			long offset = Math.max(random.nextLong(),1000000000L);
			Date from = new Date (System.currentTimeMillis()+offset);
			Date to = new Date (System.currentTimeMillis()+(2*offset));
			
			String state = "";
			switch(random.nextInt(3)){
			case 0: state = "STATE-A"; break;
			case 1: state = "STATE-B"; break;
			default: state = "STATE-C";
			}
			
			ServiceType serviceType1 = getServiceType();
			int countService1 = getServiceCounter(serviceType1);
			countService1 = random.nextInt(countService1);
			
			ServiceType serviceType2 = getServiceType();
			int countService2 = getServiceCounter(serviceType2);
			countService2 = random.nextInt(countService2);
			
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/similarity/id_"+x+"/\" relationType=\"similarity\">\n" +
					"\t<property name=\"rating\" type=\"Integer\">" + random.nextInt(5) + "</property>\n" +
					"\t<property name=\"strength\" type=\"Double\">" + random.nextDouble() + "</property>\n" +
					"\t<property name=\"start\" type=\"Date\">" + sdf.format(from) + "</property>\n" +
					"\t<property name=\"stop\" type=\"Date\">" + sdf.format(to) + "</property>\n" +
					"\t<property name=\"state\" type=\"String\">" + state + "</property>\n" +
					
					"\t<nodeRef nodeUri=\"http://sose.com/node/"+serviceType1.name()+"_"+ countService1+"\"/>\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/"+serviceType2.name()+"_"+ countService2+"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			x++;
		}
	}

	
	public void createForwardingRelationship(int count) throws IOException {

		int x = 0;
		while(x < count){
		
			long offset = Math.max(random.nextLong(),1000000000L);
			Date from = new Date (System.currentTimeMillis()+offset);
			Date to = new Date (System.currentTimeMillis()+(2*offset));
			
			String state = "";
			switch(random.nextInt(3)){
			case 0: state = "STATE-A"; break;
			case 1: state = "STATE-B"; break;
			default: state = "STATE-C";
			}
			
			ServiceType serviceType1 = ServiceType.SBS;
			int countService1 = getServiceCounter(serviceType1);
			countService1 = random.nextInt(countService1);
			
			ServiceType serviceType2 = getServiceType();
			int countService2 = getServiceCounter(serviceType2);
			countService2 = random.nextInt(countService2);
			
			out.write(
				"<hyperEdge uri=\"http://sose.com/relation/forwarding/id_"+x+"/\" relationType=\"forwarding\">\n" +
					"\t<property name=\"rating\" type=\"Integer\">" + random.nextInt(5) + "</property>\n" +
					"\t<property name=\"strength\" type=\"Double\">" + random.nextDouble() + "</property>\n" +
					"\t<property name=\"start\" type=\"Date\">" + sdf.format(from) + "</property>\n" +
					"\t<property name=\"stop\" type=\"Date\">" + sdf.format(to) + "</property>\n" +
					"\t<property name=\"state\" type=\"String\">" + state + "</property>\n" +
					
					"\t<nodeRef nodeUri=\"http://sose.com/node/"+serviceType1.name()+"_"+ countService1+"\"/>\n" +
					"\t<nodeRef nodeUri=\"http://sose.com/node/"+serviceType2.name()+"_"+ countService2+"\"/>\n" +
				"</hyperEdge>\n\n"
			);
			x++;
		}
	}	
}